package com.smedi.ismedi.authoritymanagement.core.domain.service.impl;

import com.smedi.ismedi.authority.starter.response.AuthorityAccessResponse;
import com.smedi.ismedi.authority.starter.util.AuthorityUtil;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleBasic;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleMember;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.RoleBasicRepository;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.RoleMemberRepository;
import com.smedi.ismedi.authoritymanagement.core.domain.service.RoleBasicDomainService;
import com.smedi.ismedi.authoritymanagement.core.infrastructure.constant.CustomError;
import com.smedi.ismedi.web.starter.exception.LogicException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

/**
 * @Author: xulinjun
 * @Date: 2021-8-10 14:40
 */
@Slf4j
@Service
@AllArgsConstructor
public class RoleBasicDomainServiceImpl implements RoleBasicDomainService {
    private final RoleBasicRepository roleBasicRepository;

    private final RoleMemberRepository roleMemberRepository;

    private final AuthorityUtil authorityUtil;

    @Override
    public Boolean duplicateRoleName(String roleName, Long roleId) {
        return roleBasicRepository.selectRoleNameCount(roleName, roleId) > 0;
    }

    @Override
    public RoleBasic saveRoleBasic(RoleBasic data) {
        AuthorityAccessResponse access = authorityUtil.getLoginAccess();
        RoleBasic basic;
        if (data.getRoleId() != null) {
            basic = roleBasicRepository.selectByRoleId(data.getRoleId());
            if (basic == null) {
                throw LogicException.raise(CustomError.ROLE_BASIC_NOT_EXIST);
            }
        } else {
            basic = RoleBasic.builder()
                    .createdLastName(access.getLastName())
                    .build(); // 创建人
        }

        basic.setRoleName(data.getRoleName());
        basic.setRemark(data.getRemark());
        basic.setAdmin(data.isAdmin());
        basic.setUpdatedLastName(access.getLastName()); // 更新人
        basic.setRoleType(data.getRoleType());
        // 判断当前角色名称是否重名
        if (duplicateRoleName(basic.getRoleName(), basic.getRoleId())) {
            throw LogicException.raise(CustomError.ROLE_NAME_DUPLICATE);
        }

        RoleBasic domain = (data.getRoleId() == null) ? roleBasicRepository.doInsert(basic) : roleBasicRepository.doUpdate(basic);
        return domain;
    }

    @Override
    public void deleteRoleBasicByRoleId(Long roleId) {
        RoleBasic basic = getRoleBasicByRoleId(roleId);
        if (basic == null) {
            throw LogicException.raise(CustomError.ROLE_BASIC_NOT_EXIST);
        }

        if (roleMemberRepository.selectCountByRoleId(roleId) > 0) {
            throw LogicException.raise(CustomError.ROLE_MEMBER_EXIST);
        }

        roleBasicRepository.doDeleteByRoleId(roleId);
    }

    @Override
    public RoleBasic getRoleBasicByRoleId(Long roleId) {
        RoleBasic basic = roleBasicRepository.selectByRoleId(roleId);
        if (basic == null) {
            throw LogicException.raise(CustomError.ROLE_BASIC_NOT_EXIST);
        }
        return basic;
    }

    @Override
    public Boolean hasAdminRole(Long personId) {
        List<RoleMember> roleMembers = roleMemberRepository.selectRoleMemberByPersonId(personId);

        Optional<RoleMember> optional = roleMembers.stream().filter(roleMember -> {
            RoleBasic basic = roleBasicRepository.selectByRoleId(roleMember.getRoleId());
            if (basic != null) {
                return basic.isAdmin();
            } else {
                return false;
            }
        }).findAny();

        return optional.isPresent();
    }
}
